package event

import (
	"encoding/json"
	"fmt"
	"log"
	"net/url"
	"sync"
	"time"

	"github.com/gorilla/websocket"
)

// WebSocket 客户端配置
const (
	// WebSocket服务器的地址
	ServerAddr = "localhost:8080"

	// 重连间隔（毫秒）
	ReconnectInterval = 5000
)

// WebSocket客户端类
type WebSocketClient struct {
	url                 string
	socket              *websocket.Conn
	connected           bool
	tryConnect          bool
	reconnectInterval   time.Duration
	requestCallbacks    sync.Map // 使用sync.Map来存储回调函数
	eventUpdateHandlers []func(*Event)
	reqIDMutex          sync.Mutex
	nextReqID           int
	writeMutex          sync.Mutex
}

func NewWebSocketClient(serverURL string) *WebSocketClient {
	return &WebSocketClient{
		url:               serverURL,
		connected:         false,
		tryConnect:        false,
		reconnectInterval: time.Duration(ReconnectInterval) * time.Millisecond,
		nextReqID:         0,
	}
}

func (c *WebSocketClient) Connect() error {
	// 解析URL
	uri, err := url.Parse(c.url)
	if err != nil {
		return fmt.Errorf("无法解析URL: %v", err)
	}

	// 创建WebSocket连接
	conn, _, err := websocket.DefaultDialer.Dial(uri.String(), nil)
	if err != nil {
		return fmt.Errorf("无法连接到WebSocket服务器: %v", err)
	}

	// 设置客户端状态
	c.socket = conn
	c.connected = true

	// 启动接收消息的goroutine
	go c.readMessages()

	log.Println("WebSocket连接已建立")
	return nil
}

func (c *WebSocketClient) Disconnect() {
	c.tryConnect = false
	if c.socket != nil {
		c.socket.Close()
	}
	c.connected = false
	log.Println("WebSocket连接已关闭")
}

func (c *WebSocketClient) sendFrame(frame *Frame) bool {
	if !c.connected || c.socket == nil {
		log.Println("无法发送帧: WebSocket未连接")
		return false
	}

	// 序列化帧
	message := frame.Serialize()
	// 发送消息
	c.writeMutex.Lock()
	defer c.writeMutex.Unlock()
	if err := c.socket.WriteMessage(websocket.BinaryMessage, message); err != nil {
		log.Printf("发送消息失败: %v", err)
		return false
	}

	log.Printf("已发送帧: %+v", frame)
	return true
}

func (c *WebSocketClient) handleMessage(data []byte) {
	// 反序列化帧
	var frame Frame
	if err := json.Unmarshal(data, &frame); err != nil {
		// 处理解析错误
		c.handleParseError(err)
		return
	}

	log.Printf("接收到帧: %+v", frame)

	// 处理不同类型的帧
	switch frame.Type {
	case event_update_type:
		c.handleEventUpdate(&frame)
	case response_type, error_type:
		if callback, ok := c.requestCallbacks.Load(frame.ReqID); ok {
			if cb, ok := callback.(func(*Frame)); ok {
				cb(&frame)
				c.requestCallbacks.Delete(frame.ReqID)
			} else {
				log.Printf("回调类型不匹配: %v", callback)
			}
		} else {
			log.Printf("未找到请求ID %d 的回调函数", frame.ReqID)
		}
	default:
		log.Printf("接收到未知类型的帧: %s", frame.Type)
	}
}

func (c *WebSocketClient) handleParseError(err error) {
	// 处理解析错误
	errorFrame := Frame{
		Type:  "parse_error",
		Data:  fmt.Sprintf("解析错误: %v", err),
		ReqID: -1, // 无效的请求ID
	}

	// 调用所有注册的错误处理回调
	c.requestCallbacks.Range(func(key, value interface{}) bool {
		if cb, ok := value.(func(*Frame)); ok {
			cb(&errorFrame)
		}
		return true
	})
}

func (c *WebSocketClient) handleEventUpdate(frame *Frame) {
	// 假设事件数据在frame.Data中
	bs, ok := frame.Data.([]byte)
	if !ok {
		log.Println("Data数据格式不正确")
		return
	}
	var evt Event
	err := json.Unmarshal(bs, &evt)
	if err != nil {
		log.Println("Data数据格式不是json")
		return
	}

	// 调用事件处理器
	for _, f := range c.eventUpdateHandlers {
		go f(&evt)
	}
}

func (c *WebSocketClient) sendRequest(frame *Frame) (*Frame, error) {
	if !c.connected || c.socket == nil {
		return nil, fmt.Errorf("WebSocket未连接")
	}

	// 生成唯一请求ID
	c.reqIDMutex.Lock()
	frame.ReqID = c.nextReqID
	c.nextReqID++
	c.reqIDMutex.Unlock()

	// 创建回调函数的通道
	responseChan := make(chan *Frame, 1)

	// 存储回调函数
	c.requestCallbacks.Store(frame.ReqID, func(response *Frame) {
		responseChan <- response
	})

	// 发送帧
	if !c.sendFrame(frame) {
		c.requestCallbacks.Delete(frame.ReqID)
		return nil, fmt.Errorf("发送请求失败")
	}

	// 等待响应（添加超时机制）
	select {
	case response := <-responseChan:
		return response, nil
	case <-time.After(1 * time.Second): // 超时时间设为1秒
		c.requestCallbacks.Delete(frame.ReqID)
		return nil, fmt.Errorf("请求超时")
	}
}

func (c *WebSocketClient) RegisterEventHandler(handler func(*Event)) {
	c.eventUpdateHandlers = append(c.eventUpdateHandlers, handler)
}

// WebSocket读取消息循环
func (c *WebSocketClient) readMessages() {
	for c.connected {
		// 读取消息
		_, message, err := c.socket.ReadMessage()
		if err != nil {
			log.Printf("读取消息失败: %v", err)
			c.connected = false
			if c.tryConnect {
				time.Sleep(c.reconnectInterval)
				if err := c.Connect(); err != nil {
					log.Printf("重连失败: %v", err)
				}
			}
			return
		}

		// 处理消息
		c.handleMessage(message)
	}
}

// 获取当前运行ID
func (c *WebSocketClient) GetCurrentRunID() (*Frame, error) {
	return c.sendRequest(NewReqGetCurrentRunID())
}

// 获取所有运行ID
func (c *WebSocketClient) GetAllRunIDs() (*Frame, error) {
	return c.sendRequest(NewReqGetAllRunIds())
}

// 获取指定ID的事件
func (c *WebSocketClient) GetEvent(eventID string) (*Frame, error) {
	return c.sendRequest(NewReqGetEvent(eventID))
}

// 获取多个事件
func (c *WebSocketClient) GetEvents(eventIDs []string) (*Frame, error) {
	return c.sendRequest(NewReqGetEvents(eventIDs))
}

// 获取正在处理的事件
func (c *WebSocketClient) GetProcessingEvents() (*Frame, error) {
	return c.sendRequest(NewReqGetProcessingEvents())
}

// 获取当前运行的事件
func (c *WebSocketClient) GetCurrentRunEvents() (*Frame, error) {
	return c.sendRequest(NewReqGetCurrentRunEvents())
}

// 获取当前运行的事件ID
func (c *WebSocketClient) GetCurrentRunEventIds() (*Frame, error) {
	return c.sendRequest(NewReqGetCurrentRunEventIds())
}

// 获取事件计数
func (c *WebSocketClient) GetEventCount(runID string) (*Frame, error) {
	return c.sendRequest(NewReqGetEventCount(runID))
}

// 获取特定运行的事件
func (c *WebSocketClient) GetEventsForRun(runID string, offset int, cnt int) (*Frame, error) {
	return c.sendRequest(NewReqGetEventsForRun(runID, offset, cnt))
}

// 获取所有运行
func (c *WebSocketClient) GetAllRuns() (*Frame, error) {
	return c.sendRequest(NewReqGetAllRuns())
}

func (c *WebSocketClient) GetAllParentsChildren(id string) (*Frame, error) {
	return c.sendRequest(NewReqGetAllParentsChildren(id))
}
